home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / src / demos / GL / snurb / zip.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-08-02  |  14.5 KB  |  623 lines

  1. /*
  2.  * Copyright 1991, 1992, 1993, 1994, Silicon Graphics, Inc.
  3.  * All Rights Reserved.
  4.  *
  5.  * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
  6.  * the contents of this file may not be disclosed to third parties, copied or
  7.  * duplicated in any form, in whole or in part, without the prior written
  8.  * permission of Silicon Graphics, Inc.
  9.  *
  10.  * RESTRICTED RIGHTS LEGEND:
  11.  * Use, duplication or disclosure by the Government is subject to restrictions
  12.  * as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
  13.  * and Computer Software clause at DFARS 252.227-7013, and/or in similar or
  14.  * successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
  15.  * rights reserved under the Copyright Laws of the United States.
  16.  */
  17. #include <stdio.h>
  18. #include <gl.h>
  19. #include <device.h>
  20. #include <math.h>
  21. #include "defines.h"
  22. #include "draw.h"
  23. #include "matrix.h"
  24. #include "data.h"
  25. #include "zip.h"
  26.  
  27.  
  28.  
  29. extern struct node_struct *root;
  30. static Coord dist(Coord a[3], Coord b[3]);
  31.  
  32.  
  33. /* On a four by four grid, returns true for those locations marked 'T':
  34.  * -TT-
  35.  * T--T
  36.  * T--T
  37.  * -TT-
  38.  */
  39. Boolean inner_edge(int s, int t)
  40. {
  41.     Boolean result;
  42.  
  43.     result = ( (  ((s == 1)||(s == 2)) && ((t == 0) || (t == 3)) ) ||
  44.                (  ((t == 1)||(t == 2)) && ((s == 0) || (s == 3)) ));
  45.  
  46.     return result;
  47. }
  48.  
  49.  
  50.  
  51.  
  52. void find_edges(int s, int t, int *edge1, int *edge2, Boolean *inside)
  53. {
  54.     if (s == 0)
  55.     {
  56.         if (t == 0)
  57.         {
  58.             *edge1 = 0; *edge2 = 3;
  59.             *inside = FALSE;
  60.         }
  61.         else if (t == 1)
  62.         {
  63.             *edge1 = 0; *edge2 = 3;
  64.             *inside = FALSE;
  65.         }
  66.         else if (t == 2)
  67.         {
  68.             *edge1 = 2; *edge2 = 3;
  69.             *inside = FALSE;
  70.         }
  71.         else if (t == 3)
  72.         {
  73.             *edge1 = 2; *edge2 = 3;
  74.             *inside = FALSE;
  75.         }
  76.     }
  77.     else if (s == 1)
  78.     {
  79.         if (t == 0)
  80.         {
  81.             *edge1 = 0; *edge2 = 3;
  82.             *inside = FALSE;
  83.         }
  84.         else if (t == 1)
  85.         {
  86.             *edge1 = 0; *edge2 = 3;
  87.             *inside = TRUE;
  88.         }
  89.         else if (t == 2)
  90.         {
  91.             *edge1 = 2; *edge2 = 3;
  92.             *inside = TRUE;
  93.         }
  94.         else if (t == 3)
  95.         {
  96.             *edge1 = 2; *edge2 = 3;
  97.             *inside = FALSE;
  98.         }
  99.     }
  100.     else if (s == 2)
  101.     {
  102.         if (t == 0)
  103.         {
  104.             *edge1 = 0; *edge2 = 1;
  105.             *inside = FALSE;
  106.         }
  107.         else if (t == 1)
  108.         {
  109.             *edge1 = 0; *edge2 = 1;
  110.             *inside = TRUE;
  111.         }
  112.         else if (t == 2)
  113.         {
  114.             *edge1 = 1; *edge2 = 2;
  115.             *inside = TRUE;
  116.         }
  117.         else if (t == 3)
  118.         {
  119.             *edge1 = 1; *edge2 = 2;
  120.             *inside = FALSE;
  121.         }
  122.     }
  123.     else if (s == 3)
  124.     {
  125.         if (t == 0)
  126.         {
  127.             *edge1 = 0; *edge2 = 1;
  128.             *inside = FALSE;
  129.         }
  130.         else if (t == 1)
  131.         {
  132.             *edge1 = 0; *edge2 = 1;
  133.             *inside = FALSE;
  134.         }
  135.         else if (t == 2)
  136.         {
  137.             *edge1 = 1; *edge2 = 2;
  138.             *inside = FALSE;
  139.         }
  140.         else if (t == 3)
  141.         {
  142.             *edge1 = 1; *edge2 = 2;
  143.             *inside = FALSE;
  144.         }
  145.     }
  146. }
  147.  
  148.  
  149.  
  150.  
  151.  
  152. /* returns what edge a given INNER edge point is on. edges are numbered 
  153.  * counter-clockwise,
  154.  * starting at the bottom (t = 0)
  155.  */
  156. int find_zip_edge(int s, int t)
  157. {
  158.     int result;
  159.  
  160.     if ((t == 1)||(t == 2))
  161.     {
  162.         if (s == 0)
  163.             result = 3;
  164.         else if (s == 3)
  165.             result = 1;
  166.         else
  167.             result = NONE;
  168.     }
  169.     else if ((s == 1)||(s == 2))
  170.     {
  171.         if (t == 0)
  172.             result = 0;
  173.         else if (t == 3)
  174.             result = 2;
  175.         else
  176.             result = NONE;
  177.     }
  178.     else
  179.         result = NONE;
  180.  
  181.     return result;
  182. }
  183.     
  184.     
  185.  
  186.             
  187.  
  188.  
  189. void zip_patches(
  190.     struct node_struct *source,
  191.     struct node_struct *dest,
  192.     int source_s, int source_t,
  193.     int dest_s, int dest_t,
  194.     int tool)
  195. {
  196.     int i,j;
  197.     int source_edge, dest_edge, edge1, edge2;
  198.     Coord delta;
  199.     Boolean inside;
  200.  
  201.     /* edge counting */
  202.     int source_s_index, source_t_index, dest_s_index, dest_t_index;
  203.     int source_s_step, source_t_step, dest_s_step, dest_t_step;
  204.  
  205.     /* inner counting */
  206.     int i_source_s_index, i_source_t_index, i_dest_s_index, i_dest_t_index;
  207.     int i_source_s_step, i_source_t_step, i_dest_s_step, i_dest_t_step;
  208.  
  209.  
  210.     /** Setup source and destination edge structures **/
  211.     source_edge = find_zip_edge(source_s, source_t);
  212.     dest_edge = find_zip_edge(dest_s, dest_t); 
  213.  
  214.     source->patch->zipper[source_edge]->zip_type = tool;
  215.     dest->patch->zipper[dest_edge]->zip_type = tool;
  216.  
  217.     source->patch->zipper[source_edge]->patch = dest;
  218.     dest->patch->zipper[dest_edge]->patch = source;
  219.  
  220.     /* The edge field tells which edge on the other patch this edge effects */
  221.     source->patch->zipper[source_edge]->edge = dest_edge;
  222.     dest->patch->zipper[dest_edge]->edge = source_edge;
  223.  
  224.     
  225.     if ((source_s == 0)||(source_s == 3))
  226.     {
  227.         source_s_index = source_s;
  228.         source_s_step = 0;
  229.  
  230.         i_source_s_index = abs(source_s - 1); /* 1 or 2 */
  231.         i_source_s_step = 0;
  232.     }
  233.     else
  234.     {
  235.         if (source_s == 1)
  236.         {
  237.             i_source_s_index = source_s_index = 0;
  238.             i_source_s_step = source_s_step = 1;
  239.         }
  240.         else
  241.         {
  242.             i_source_s_index = source_s_index = 3;
  243.             i_source_s_step = source_s_step = -1;
  244.         }
  245.     }
  246.     
  247.     if ((source_t == 0)||(source_t == 3))
  248.     {
  249.         source_t_index = source_t;
  250.         source_t_step = 0;
  251.         
  252.         i_source_t_index = abs(source_t - 1); /* 1 or 2 */
  253.         i_source_t_step = 0;
  254.     }
  255.     else
  256.     {
  257.         if (source_t == 1)
  258.         {
  259.             i_source_t_index = source_t_index = 0;
  260.             i_source_t_step = source_t_step = 1;
  261.         }
  262.         else
  263.         {
  264.             i_source_t_index = source_t_index = 3;
  265.             i_source_t_step = source_t_step = -1;
  266.         }
  267.     }
  268.  
  269.  
  270.     
  271.     if ((dest_s == 0)||(dest_s == 3))
  272.     {
  273.         dest_s_index = dest_s;
  274.         dest_s_step = 0;
  275.  
  276.         i_dest_s_index = abs(dest_s - 1); /* 1 or 2 */
  277.         i_dest_s_step = 0;
  278.     }
  279.     else
  280.     {
  281.         if (dest_s == 1)
  282.         {
  283.             i_dest_s_index = dest_s_index = 0;
  284.             i_dest_s_step = dest_s_step = 1;
  285.         }
  286.         else
  287.         {
  288.             i_dest_s_index = dest_s_index = 3;
  289.             i_dest_s_step = dest_s_step = -1;
  290.         }
  291.     }
  292.     
  293.     if ((dest_t == 0)||(dest_t == 3))
  294.     {
  295.         dest_t_index = dest_t;
  296.         dest_t_step = 0;
  297.         
  298.         i_dest_t_index = abs(dest_t - 1); /* 1 or 2 */
  299.         i_dest_t_step = 0;
  300.     }
  301.     else
  302.     {
  303.         if (dest_t == 1)
  304.         {
  305.             i_dest_t_index = dest_t_index = 0;
  306.             i_dest_t_step = dest_t_step = 1;
  307.         }
  308.         else
  309.         {
  310.             i_dest_t_index = dest_t_index = 3;
  311.             i_dest_t_step = dest_t_step = -1;
  312.         }
  313.     }
  314.  
  315.     source->patch->zipper[source_edge]->s_index = source_s_index;
  316.     source->patch->zipper[source_edge]->s_step = source_s_step;
  317.     source->patch->zipper[source_edge]->t_index = source_t_index;
  318.     source->patch->zipper[source_edge]->t_step = source_t_step;
  319.     
  320.     dest->patch->zipper[dest_edge]->s_index = dest_s_index;
  321.     dest->patch->zipper[dest_edge]->s_step = dest_s_step;
  322.     dest->patch->zipper[dest_edge]->t_index = dest_t_index;
  323.     dest->patch->zipper[dest_edge]->t_step = dest_t_step;
  324.     
  325.     source->patch->zipper[source_edge]->i_s_index = i_source_s_index;
  326.     source->patch->zipper[source_edge]->i_s_step = i_source_s_step;
  327.     source->patch->zipper[source_edge]->i_t_index = i_source_t_index;
  328.     source->patch->zipper[source_edge]->i_t_step = i_source_t_step;
  329.     
  330.     dest->patch->zipper[dest_edge]->i_s_index = i_dest_s_index;
  331.     dest->patch->zipper[dest_edge]->i_s_step = i_dest_s_step;
  332.     dest->patch->zipper[dest_edge]->i_t_index = i_dest_t_index;
  333.     dest->patch->zipper[dest_edge]->i_t_step = i_dest_t_step;
  334.     
  335.     for (i=0; i<4; i++)
  336.     {
  337.         /* match up edge control points */
  338.         for (j=0; j<3; j++)
  339.         {
  340.             dest->patch->control[dest_s_index][dest_t_index][j] = 
  341.                 source->patch->control[source_s_index][source_t_index][j];
  342.         }
  343.  
  344.         clear_zip_effects(root->child);
  345.         move_zipped_points(dest, dest_s_index, dest_t_index);
  346.         clear_zip_effects(root->child);
  347.         move_zipped_points(dest, dest_s_index, dest_t_index);
  348.  
  349.         /* if round zipping, force inner control points colinear */
  350.         if ((source->patch->zipper[source_edge]->zip_type == SMOOTH_ZIP_TOOL) ||
  351.             (source->patch->zipper[source_edge]->zip_type == ROUND_ZIP_TOOL))
  352.         {
  353.             for (j=0; j<3; j++)
  354.             {        
  355.                 delta = source->patch->control[source_s_index][source_t_index][j] -
  356.                     source->patch->control[i_source_s_index][i_source_t_index][j];
  357.  
  358.                 dest->patch->control[i_dest_s_index][i_dest_t_index][j] =
  359.                     dest->patch->control[dest_s_index][dest_t_index][j] + delta;
  360.             }
  361.  
  362.             clear_zip_effects(root->child);
  363.             move_zipped_points(dest, i_dest_s_index, i_dest_t_index);
  364.             clear_zip_effects(root->child);
  365.             move_zipped_points(dest, i_dest_s_index, i_dest_t_index);
  366.         } 
  367.  
  368.         
  369.         source_s_index += source_s_step;
  370.         source_t_index += source_t_step;
  371.         i_source_s_index += i_source_s_step;
  372.         i_source_t_index += i_source_t_step;
  373.         
  374.         dest_s_index += dest_s_step;
  375.         dest_t_index += dest_t_step;
  376.         i_dest_s_index += i_dest_s_step;
  377.         i_dest_t_index += i_dest_t_step;
  378.     }
  379.  
  380.     source->patch->zipper[source_edge]->zipped = TRUE;
  381.     dest->patch->zipper[dest_edge]->zipped = TRUE;
  382.  
  383.  
  384. }
  385.  
  386.  
  387.  
  388.  
  389. /* Call this with a counter to prevent recursion racing */
  390. void move_affected_points(
  391.     struct node_struct *source,
  392.     int source_edge,
  393.     int s, int t)
  394. {
  395.     struct node_struct *dest;
  396.     int i,j;
  397.     int source_s_index, source_t_index, dest_s_index, dest_t_index;
  398.     int source_s_step, source_t_step, dest_s_step, dest_t_step;
  399.     int i_source_s_index, i_source_t_index, i_dest_s_index, i_dest_t_index;
  400.     int i_source_s_step, i_source_t_step, i_dest_s_step, i_dest_t_step;
  401.     int edge1, edge2;
  402.     Boolean inside;
  403.     
  404.     Coord delta;
  405.     int dest_edge;
  406.     
  407.     dest = source->patch->zipper[source_edge]->patch;
  408.     dest_edge = source->patch->zipper[source_edge]->edge;
  409.     
  410.     source_s_step = source->patch->zipper[source_edge]->s_step;
  411.     source_s_index = source->patch->zipper[source_edge]->s_index;
  412.     source_t_step = source->patch->zipper[source_edge]->t_step;
  413.     source_t_index = source->patch->zipper[source_edge]->t_index;
  414.  
  415.     dest_s_step = dest->patch->zipper[dest_edge]->s_step;
  416.     dest_s_index = dest->patch->zipper[dest_edge]->s_index;
  417.     dest_t_step = dest->patch->zipper[dest_edge]->t_step;
  418.     dest_t_index = dest->patch->zipper[dest_edge]->t_index;
  419.  
  420.     i_source_s_step = source->patch->zipper[source_edge]->i_s_step;
  421.     i_source_s_index = source->patch->zipper[source_edge]->i_s_index;
  422.     i_source_t_step = source->patch->zipper[source_edge]->i_t_step;
  423.     i_source_t_index = source->patch->zipper[source_edge]->i_t_index;
  424.  
  425.     i_dest_s_step = dest->patch->zipper[dest_edge]->i_s_step;
  426.     i_dest_s_index = dest->patch->zipper[dest_edge]->i_s_index;
  427.     i_dest_t_step = dest->patch->zipper[dest_edge]->i_t_step;
  428.     i_dest_t_index = dest->patch->zipper[dest_edge]->i_t_index;
  429.  
  430.  
  431.     
  432.     for (i=0; i<4; i++)
  433.     {
  434.  
  435.         if (source->patch->zipper[source_edge]->zip_type == SHARP_ZIP_TOOL)
  436.         {
  437.             if ((source_s_index == s) && (source_t_index == t))
  438.             {
  439.                 if (! dest->patch->affected[dest_s_index][dest_t_index])
  440.                 {
  441.                     for (j=0; j<3; j++)
  442.                     {
  443.                         dest->patch->affected[dest_s_index][dest_t_index] =    TRUE;
  444.                         
  445.                         dest->patch->control[dest_s_index][dest_t_index][j] =
  446.                             source->patch->control[source_s_index][source_t_index][j];
  447.                     }
  448.  
  449.                     move_zipped_points(dest, dest_s_index, dest_t_index);
  450.                 }
  451.             }
  452.         }
  453.         else if ((source->patch->zipper[source_edge]->zip_type == SMOOTH_ZIP_TOOL) ||
  454.                     (source->patch->zipper[source_edge]->zip_type == ROUND_ZIP_TOOL))
  455.         {
  456.             if ((source_s_index == s) && (source_t_index == t))
  457.             {
  458.                 /* edge control point */
  459.                 if (! dest->patch->affected[dest_s_index][dest_t_index])
  460.                 {
  461.                     for (j=0; j<3; j++)
  462.                     {
  463.                         delta =
  464.                             source->patch->control[source_s_index][source_t_index][j] - 
  465.                             dest->patch->control[dest_s_index][dest_t_index][j];
  466.                             
  467.                         dest->patch->control[dest_s_index][dest_t_index][j] += delta;
  468.                         source->patch->control[i_source_s_index][i_source_t_index][j] += delta;
  469.                         dest->patch->control[i_dest_s_index][i_dest_t_index][j] += delta;
  470.                     }
  471.                     move_zipped_points(source, i_source_s_index, i_source_t_index);
  472.                     move_zipped_points(dest, i_dest_s_index, i_dest_t_index);
  473.                     move_zipped_points(dest, dest_s_index, dest_t_index);
  474.                 }
  475.                     
  476.             }
  477.             else if ((i_source_s_index == s) && (i_source_t_index == t))
  478.             {
  479.                 if (! dest->patch->affected[i_dest_s_index][i_dest_t_index])
  480.                 {
  481.                     if (source->patch->zipper[source_edge]->zip_type == ROUND_ZIP_TOOL)
  482.                     {
  483.                         for (j=0; j<3; j++)
  484.                         {
  485.                             delta = 
  486.                                 source->patch->control[i_source_s_index][i_source_t_index][j] -
  487.                                 source->patch->control[source_s_index][source_t_index][j];
  488.  
  489.                             dest->patch->control[i_dest_s_index][i_dest_t_index][j] =
  490.                                 dest->patch->control[dest_s_index][dest_t_index][j] - delta;
  491.                         }
  492.                     }
  493.                     else /* SMOOTH ZIP TOOL */
  494.                     {
  495.                         Coord dab,dbc;
  496.  
  497.                         dab = dist(source->patch->control[i_source_s_index][i_source_t_index],
  498.                                    source->patch->control[source_s_index][source_t_index]);
  499.  
  500.                         dbc = dist(dest->patch->control[i_dest_s_index][i_dest_t_index],
  501.                                    dest->patch->control[dest_s_index][dest_t_index]);
  502.  
  503.                         for (j=0; j<3; j++)
  504.                         {
  505.                             delta = 
  506.                                 source->patch->control[source_s_index][source_t_index][j] -
  507.                                 source->patch->control[i_source_s_index][i_source_t_index][j];
  508.  
  509.                             dest->patch->control[i_dest_s_index][i_dest_t_index][j] =
  510.                                 dest->patch->control[dest_s_index][dest_t_index][j] +
  511.                                 delta*dbc/dab;
  512.                         }
  513.                     }
  514.                     
  515.                     move_zipped_points(dest, i_dest_s_index, i_dest_t_index);
  516.                 }
  517.             }
  518.         }
  519.         
  520.         dest_s_index += dest_s_step;
  521.         dest_t_index += dest_t_step;
  522.         source_s_index += source_s_step;
  523.         source_t_index += source_t_step;
  524.         
  525.         i_dest_s_index += i_dest_s_step;
  526.         i_dest_t_index += i_dest_t_step;
  527.         i_source_s_index += i_source_s_step;
  528.         i_source_t_index += i_source_t_step;
  529.  
  530.     }    
  531. }
  532.  
  533.  
  534. static Coord dist(Coord a[3], Coord b[3])
  535. {
  536.     return(fsqrt( (a[0]-b[0])*(a[0]-b[0]) + (a[1]-b[1])*(a[1]-b[1]) + (a[2]-b[2])*(a[2]-b[2])));
  537. }
  538.  
  539.  
  540. void move_zipped_points(
  541.     struct node_struct *source,
  542.     int s, int t)
  543. {
  544.     int edge1, edge2;
  545.     Boolean inside;
  546.  
  547.     /* find the two edge */
  548.     find_edges(s, t, &edge1, &edge2, &inside);
  549.  
  550.     source->patch->affected[s][t] = TRUE;
  551.  
  552.     if (source->patch->zipper[edge1]->zipped)
  553.         if ((!inside) || (inside &&
  554.             (source->patch->zipper[edge1]->zip_type != SHARP_ZIP_TOOL)))
  555.         {
  556.             move_affected_points(source,edge1,s,t);
  557.         }
  558.  
  559.     if (source->patch->zipper[edge2]->zipped)
  560.         if ((!inside) || (inside &&
  561.             (source->patch->zipper[edge2]->zip_type != SHARP_ZIP_TOOL)))
  562.         {
  563.             source->patch->affected[s][t] = TRUE;
  564.             move_affected_points(source,edge2,s,t);
  565.         }
  566. }
  567.  
  568.  
  569.  
  570.  
  571. void clear_zip_effects(struct node_struct *child)
  572. {
  573.     int i,j;
  574.     
  575.     if (child != NULL)
  576.     {
  577.         if (child->node_type == PATCH)
  578.             for (i=0; i<4; i++)
  579.                 for (j=0; j<4; j++)
  580.                     child->patch->affected[i][j] = FALSE;
  581.  
  582.         clear_zip_effects(child->child);
  583.         clear_zip_effects(child->sibling);
  584.     }
  585. }
  586.         
  587.             
  588.             
  589.                 
  590.  
  591.  
  592. /* if any of the edges of this patch are zipped, unzip them */
  593. void unzip_edge(struct node_struct *source_patch, int source_edge)
  594. {
  595.     int dest_edge;
  596.     struct node_struct *dest_patch;
  597.     
  598.     if (source_patch->patch->zipper[source_edge]->zipped)
  599.     {
  600.         source_patch->patch->zipper[source_edge]->zipped = FALSE;
  601.  
  602.         /* Make the patch that points to this point to NULL */
  603.         dest_edge = source_patch->patch->zipper[source_edge]->edge;
  604.         dest_patch = source_patch->patch->zipper[source_edge]->patch;
  605.         
  606.         dest_patch->patch->zipper[dest_edge]->zipped = FALSE;
  607.         dest_patch->patch->zipper[dest_edge]->patch = NULL;
  608.             
  609.         source_patch->patch->zipper[source_edge]->patch = NULL;
  610.     }
  611. }
  612.  
  613.  
  614.  
  615. /* if any of the edges of this patch are zipped, unzip them */
  616. void unzip_all(struct node_struct *source_patch)
  617. {
  618.     int i;
  619.     
  620.     for (i = 0; i < 4; i++)
  621.         unzip_edge(source_patch, i);
  622. }
  623.